#include <iostream>
#include <vector>
#include <gtkmm.h>
#include <pqxx/pqxx>
using namespace PGSTD;
using namespace pqxx;
class ExampleWindow : public Gtk::Window
{
	public:
		ExampleWindow();
		virtual ~ExampleWindow();
	protected:
		virtual void on_button_quit();
		virtual void on_button_refresh();
		class ModelColumns : public Gtk::TreeModel::ColumnRecord
	{
		public:
			vector<Gtk::TreeModelColumn<Glib::ustring> >vm_col_name;
	};
		Gtk::VBox m_VBox;
		Gtk::HBox m_HBox;
		Gtk::ScrolledWindow m_ScrolledWindow;
		Gtk::TreeView m_TreeView;
		Glib::RefPtr<Gtk::ListStore> m_refTreeModel;
		Gtk::HButtonBox m_ButtonBox;
		Gtk::Button m_Button_Quit,m_Button_Refresh;
		Gtk::Entry m_Entry_database,m_Entry_table;
		Gtk::Label m_Label_database,m_Label_table;
};
ExampleWindow::ExampleWindow()
	: m_Button_Quit("Quit"),m_Button_Refresh("Refresh"),
	m_Label_database(" database: "),m_Label_table(" table: ")
{
	set_title("PostgreSQL table list");
	set_border_width(5);
	set_default_size(400, 200);
	m_Label_database.set_alignment(Gtk::ALIGN_RIGHT,Gtk::ALIGN_CENTER);
	m_Label_table.set_alignment(Gtk::ALIGN_RIGHT,Gtk::ALIGN_CENTER);
	add(m_VBox);
	m_ScrolledWindow.add(m_TreeView);
	m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	m_VBox.pack_start(m_ScrolledWindow);
	m_VBox.pack_start(m_HBox, Gtk::PACK_SHRINK);
	m_HBox.pack_start(m_Label_database, Gtk::PACK_SHRINK);
	m_Entry_database.set_width_chars(10);
	m_Entry_database.set_text("freevalley");
	m_Entry_database.select_region(0, m_Entry_database.get_text_length() );
	m_Entry_database.set_activates_default();
	m_HBox.pack_start(m_Entry_database, Gtk::PACK_SHRINK);
	m_HBox.pack_start(m_Label_table, Gtk::PACK_SHRINK);
	m_Entry_table.set_width_chars(8);
	m_Entry_table.set_text("users");
//	m_Entry_table.select_region(0, m_Entry_table.get_text_length() );
	m_Entry_table.set_activates_default();
	m_Entry_database.grab_focus();
	m_HBox.pack_start(m_Entry_table, Gtk::PACK_SHRINK);
	m_HBox.pack_end(m_ButtonBox, Gtk::PACK_SHRINK);
	m_ButtonBox.pack_start(m_Button_Refresh, Gtk::PACK_SHRINK);
	m_Button_Refresh.set_flags(Gtk::CAN_DEFAULT | Gtk::HAS_DEFAULT);
	m_Button_Refresh.grab_default();
	m_Button_Refresh.signal_clicked().connect( sigc::mem_fun(*this,
				&ExampleWindow::on_button_refresh) );
	m_Button_Refresh.signal_activate().connect( sigc::mem_fun(*this,
				&ExampleWindow::on_button_refresh) );
	m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK);
	m_ButtonBox.set_border_width(5);
	m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
	m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this,
				&ExampleWindow::on_button_quit) );
	on_button_refresh();
	show_all_children();
}
ExampleWindow::~ExampleWindow()
{
}
void ExampleWindow::on_button_refresh()
{
	ModelColumns m_Columns;
	m_TreeView.remove_all_columns();
	try
	{
		connection Conn("dbname="+m_Entry_database.get_text()+" user=postgres");
		work Xaction(Conn, "pqxxlist");
		result R(Xaction.exec("SELECT * from "+m_Entry_table.get_text() ) );
		for (unsigned int j=0;j<R.columns();j++)
		{
			m_Columns.vm_col_name.push_back(Gtk::TreeModelColumn<Glib::ustring>() );
			m_Columns.add(m_Columns.vm_col_name[j]);
		}
		m_refTreeModel = Gtk::ListStore::create(m_Columns);
		m_TreeView.set_model(m_refTreeModel);
		for (result::const_iterator i = R.begin(); i != R.end(); ++i)
		{
			Gtk::TreeModel::Row row = *(m_refTreeModel->append() );
			for (unsigned int j=0;j<R.columns();j++)
				row[m_Columns.vm_col_name[j]]=i[j].c_str();
		}
		for (unsigned int j=0;j<R.columns();j++)
			m_TreeView.append_column(R.begin()[j].name(), m_Columns.vm_col_name[j]);
		for(guint i = 0; i < R.columns(); i++)
		{
			Gtk::TreeView::Column* pColumn = m_TreeView.get_column(i);
			pColumn->set_reorderable();
		}
		Xaction.commit();
		Conn.disconnect();
	}
	catch(sql_error &e)
	{
		cerr<<e.what()<<endl;
		Gtk::MessageDialog md(e.what(),false,Gtk::MESSAGE_WARNING,Gtk::BUTTONS_OK,true);
		md.run();
		return;
	}
	catch(const broken_connection &c)
	{
		cerr<<c.what()<<endl;
		Gtk::MessageDialog md(c.what(),false,Gtk::MESSAGE_WARNING,Gtk::BUTTONS_OK,true);
		md.run();
		return;
	}
	catch(...)
	{
		cerr<<"unknow exception"<<endl;
		Gtk::MessageDialog md("unknow exception",false,
				Gtk::MESSAGE_WARNING,Gtk::BUTTONS_OK,true);
		md.run();
	}
	m_TreeView.show();
}
void ExampleWindow::on_button_quit()
{
	hide();
}
int main(int argc, char *argv[])
{
	Gtk::Main kit(argc, argv);
	ExampleWindow window;
	Gtk::Main::run(window);
	return 0;
}

